package com.sy.simpleegg.ui.dialog

import android.content.DialogInterface
import android.os.Bundle
import android.text.method.HideReturnsTransformationMethod
import android.text.method.PasswordTransformationMethod
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction
import com.bumptech.glide.Glide
import com.sy.simpleegg.R
import com.sy.simpleegg.constant.Constant
import com.sy.simpleegg.constant.Constant.PWD_DEFAULT
import com.sy.simpleegg.constant.Constant.PWD_ERR_INTERVAL
import com.sy.simpleegg.constant.Constant.PWD_ERR_LIMIT_TIME
import com.sy.simpleegg.constant.Constant.PWD_ERR_MAX_COUNT
import com.sy.simpleegg.constant.Constant.PWD_MAX_LENGTH
import com.sy.simpleegg.databinding.DialogKeyboardBinding
import com.sy.simpleegg.ext.countDown
import com.sy.simpleegg.ext.logFile
import com.sy.simpleegg.util.Preference
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.cancel


class KeyboardDialog(
    private var keyboardListener: KeyboardListener,
): DialogFragment() {

    private lateinit var binding: DialogKeyboardBinding

    private var timeDownScope: CoroutineScope? = null

    private var lastClickTime = 0L

    /**
     * 密码
     */
    private var correctPassword: String by Preference(Constant.SETTING_PWD, PWD_DEFAULT)
    /**
     * 密码错误间隔
     */
    private var errInterval: Int by Preference(Constant.SETTING_PWD_INTERVAL, PWD_ERR_INTERVAL)
    /**
     * 密码错误信息 次数,错误时间
     */
    private var errInfo: String by Preference(Constant.SETTING_PWD_ERR_COUNT, "0,0")

    private var password: String = ""

    override fun onStart() {
        super.onStart()
//        dialog!!.window!!.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)

        val width = resources.getDimensionPixelSize(R.dimen.keyboard_width)
        val height = resources.getDimensionPixelSize(R.dimen.keyboard_height)
        val marginBottom = resources.getDimensionPixelSize(R.dimen.keyboard_margin_bottom)

        dialog!!.window!!.setLayout(width, height + marginBottom)
        dialog!!.window!!.setGravity(Gravity.BOTTOM)
        dialog!!.setCanceledOnTouchOutside(false)
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?,
    ): View? {
        binding = DialogKeyboardBinding.inflate(inflater, container, false)
//        setStyle(STYLE_NO_TITLE, R.style.MyDialog)
//        getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT))
//        dialog!!.window!!.setGravity(Gravity.BOTTOM)
        dialog!!.window!!.setBackgroundDrawableResource(R.color.transparent)
//        var wlp = dialog!!.window!!.attributes
//        wlp.gravity = Gravity.BOTTOM
//        wlp.width = WindowManager.LayoutParams.MATCH_PARENT
//        wlp.height = WindowManager.LayoutParams.MATCH_PARENT
//        dialog!!.window!!.attributes = wlp

        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        try {
            binding.ivClose.setOnClickListener {
                dismissAllowingStateLoss()
            }
            binding.btnLogin.setOnClickListener {
                if (!isFirstClick()) {
                    return@setOnClickListener
                }
                startCountDown()
                if (password.isEmpty()){
                    keyboardListener.showTips(resources.getString(R.string.pwd_null))
                    return@setOnClickListener
                }
                if (verify()){
                    keyboardListener.openBackstage()
                    dismissAllowingStateLoss()
                }else{
                    showView()
                    keyboardListener.showTips(resources.getString(R.string.pwd_err_keyboard))
                }
            }
            binding.keyOne.setOnClickListener {
                entryPwd("1")
            }
            binding.keyTwo.setOnClickListener {
                entryPwd("2")
            }
            binding.keyThree.setOnClickListener {
                entryPwd("3")
            }
            binding.keyFour.setOnClickListener {
                entryPwd("4")
            }
            binding.keyFive.setOnClickListener {
                entryPwd("5")
            }
            binding.keySix.setOnClickListener {
                entryPwd("6")
            }
            binding.keySeven.setOnClickListener {
                entryPwd("7")
            }
            binding.keyEight.setOnClickListener {
                entryPwd("8")
            }
            binding.keyNine.setOnClickListener {
                entryPwd("9")
            }
            binding.keyZero.setOnClickListener {
                entryPwd("0")
            }
            binding.keyDot.setOnClickListener {
                entryPwd(".")
            }
            binding.keyDel.setOnClickListener {
                delPwd()
            }
            binding.cbShowPwd.setOnCheckedChangeListener { buttonView, isChecked ->
                startCountDown()
                if (isChecked){
                    binding.etPwd.transformationMethod = HideReturnsTransformationMethod.getInstance()
                }else{
                    binding.etPwd.transformationMethod = PasswordTransformationMethod.getInstance()
                }
            }
            showView()
        }catch (e: Exception){
            e.printStackTrace()
            logFile("初始化页面异常：${e.message}")
        }
    }

    private fun showView(){
        try {
            val errCount = errInfo.split(",")[0].toInt()
            val errTime = errInfo.split(",")[1].toLong()

            val curTime = System.currentTimeMillis()
            var enable = true
            when {
                errCount >= PWD_ERR_MAX_COUNT && curTime - errTime < PWD_ERR_LIMIT_TIME * 60 * 1000L -> {
                    enable = false
                    binding.tvTips.text = resources.getString(R.string.pwd_input_err)
                    binding.llErrCount.visibility = View.GONE
                }

                errCount in 1 until PWD_ERR_MAX_COUNT && curTime - errTime < errInterval * 1000L -> {
                    binding.tvTips.text = resources.getString(R.string.pwd_input_tips)
                    binding.tvTips.visibility = View.GONE
                    binding.llErrCount.visibility = View.VISIBLE
                    binding.tvErrCount.text = errCount.toString()
                }

                else -> {
                    binding.llErrCount.visibility = View.GONE
                    binding.tvTips.text = resources.getString(R.string.pwd_input_tips)
                }
            }

            binding.etPwd.isFocusable = enable
            binding.cbShowPwd.visibility = if (enable) View.VISIBLE else View.GONE
            binding.cbShowPwd.isChecked = false

            binding.keyOne.isEnabled = enable
            binding.keyTwo.isEnabled = enable
            binding.keyThree.isEnabled = enable
            binding.keyFour.isEnabled = enable
            binding.keyFive.isEnabled = enable
            binding.keySix.isEnabled = enable
            binding.keySeven.isEnabled = enable
            binding.keyEight.isEnabled = enable
            binding.keyNine.isEnabled = enable
            binding.keyZero.isEnabled = enable
            binding.keyDot.isEnabled = enable
            Glide.with(binding.root)
                .load(if (enable) R.mipmap.ic_del_enable else R.mipmap.ic_del_disable)
                .fitCenter()
                .into(binding.ivDel)
            binding.btnLogin.isEnabled = password.isNotEmpty()
        }catch (e: Exception){
            e.printStackTrace()
            logFile("更新键盘页面异常：${e.message}")
        }
    }

    override fun onDismiss(dialog: DialogInterface) {
        super.onDismiss(dialog)
        keyboardListener.dismiss()
    }

    override fun showNow(manager: FragmentManager, tag: String?) {
        super.showNow(manager, tag)
        startCountDown()
    }

    override fun show(manager: FragmentManager, tag: String?) {
        super.show(manager, tag)
        startCountDown()
    }

    override fun show(transaction: FragmentTransaction, tag: String?): Int {
        val result = super.show(transaction, tag)
        startCountDown()
        return result

    }

    private fun entryPwd(s: String){
        try {
            startCountDown()
            if (password.length >= PWD_MAX_LENGTH) {
                keyboardListener.showTips(resources.getString(R.string.pwd_lenght_err))
                return
            }
            password += s
            binding.etPwd.setText(password)
            binding.btnLogin.isEnabled = password.isNotEmpty()
        }catch (e: Exception){
            e.printStackTrace()
            logFile("输入密码异常：${e.message}")
        }
    }

    private fun delPwd(){
        try {
            startCountDown()
            password = when {
                password.isEmpty() -> {
                    keyboardListener.showTips(resources.getString(R.string.pwd_lenght_zero))
                    return
                }

                password.length == 1 -> {
                    ""
                }

                else -> {
                    password.substring(0, password.length - 1)
                }
            }
            binding.etPwd.setText(password)
            binding.btnLogin.isEnabled = password.isNotEmpty()
        }catch (e: Exception){
            e.printStackTrace()
            logFile("删除密码异常：${e.message}")
        }
    }

    private fun verify(): Boolean{
        try {
            val result = password == correctPassword
            if (!result) {
                val errCount = errInfo.split(",")[0].toInt()
                val errTime = errInfo.split(",")[1].toLong()

                val curTime = System.currentTimeMillis()
                var curErrCount = 0
                curErrCount = if (curTime - errTime >= errInterval * 1000L) {
                    1
                } else {
                    errCount + 1
                }

                errInfo = "$curErrCount,$curTime"
            }else{
                errInfo = "0,0"
            }
            return result
        }catch (e: Exception){
            e.printStackTrace()
            logFile("校验密码异常：${e.message}")
            return false
        }
    }

    private fun startCountDown(){

        timeDownScope?.cancel()

        countDown(
            time = 30,
            start = {
                timeDownScope = it
            },
            end = {

            },
            next = {
                if (it == 0){
                    dismiss()
                }
            })
    }

    private fun isFirstClick(): Boolean{
        val currentClickTime = System.currentTimeMillis()
        val canClick = currentClickTime - lastClickTime >= Constant.CLICK_INTERVAL
        lastClickTime = currentClickTime
        return canClick
    }

    interface KeyboardListener{
        fun dismiss()

        fun openBackstage()
        fun showTips(string: String)
    }
}